<template>
  <section class="component data-box">
    <div v-if="showTopSlot" class="location">
      <div class="row between-span">
        <div>
          <slot name="buttons"></slot>
        </div>
        <div>
          <slot name="append"></slot>
        </div>
      </div>

      <div>
        <slot name="caseTotalInfo"></slot>
      </div>
    </div>
    <div class="table">
      <el-table
        :cell-style="cellStyle"
        :data="data"
        :emptyText="emptyText"
        :highlight-current-row="selectionRow != undefined"
        :row-class-name="rowClassName"
        :row-style="rowStyle"
        :span-method="spanMethod"
        :stripe="stripe && !showCaseMark"
        @current-change="updateSelectionRow"
        @row-click="onRowClick"
        @select="updateSelectionList"
        @select-all="updateSelectionList"
        @sort-change="onSortChange"
        border
        ref="table"
        tooltip-effect="dark"
        :height="tableHeight()"
        :header-cell-class-name="cellClass"
      >
        <!-- <el-table-column width="60" v-if="isSelectAll">
          <template slot="header" slot-scope="scope">
            <el-checkbox v-model="scope.row" disabled></el-checkbox>
          </template>
          <template slot-scope="scoped">
            <el-checkbox v-model="scoped.row" disabled></el-checkbox>
          </template>
        </el-table-column> -->
        <el-table-column
          type="selection"
          v-if="selectionList"
          width="50"
          :selectable="checkbox"
        />
        <el-table-column
          :label="indexLabel"
          type="index"
          v-if="!hiddenIndex"
          width="60"
        ></el-table-column>
        <slot name="columns"></slot>
      </el-table>
    </div>
    <div class="row between-span">
      <div class="databox-title">
        <slot name="footer"></slot>
      </div>
      <el-pagination
        :current-page.sync="page.pageIndex"
        :layout="page.layout"
        :page-size.sync="page.pageSize"
        :page-sizes="page.pageSizeOpts"
        :total="page.total"
        @current-change="pageIndexChange"
        @size-change="pageSizeChange"
        size="small"
        v-if="showPage && page && data && data.length > 0"
      ></el-pagination>
    </div>
  </section>
</template>

<script lang="ts">
import Vue from "vue";
import Component from "vue-class-component";
import { Watch, Prop, Emit } from "vue-property-decorator";
import { PageService } from "~/utils/page.service";
import { SortService } from "~/utils/sort.service";
import { Table } from "element-ui";
import { CaseMarkColor } from "~/config/enum.config";
import { State, Getter, namespace } from 'vuex-class'

@Component({
  components: {}
})
export default class DataBox extends Vue {
  public table: any;
  @State private userData
  private rowIndex: number = -1;
  @Prop({ default: false }) private approvalUse
  @Prop({ default: false }) private isSelectAll: boolean;
  // 数据列表

  @Prop() private data: any[];
  // 分页数据
  @Prop() private page: PageService;
  // 隐藏分页
  @Prop({ default: true })
  private showPage: any;
  // 分页数据
  @Prop() private sort: SortService;
  // 选择列表
  @Prop() private selectionList: any;
  // 选择项
  @Prop() private selectionRow: any;
  @Prop({ default: 528 })
  private maxHeight: number;
  @Prop() private height: any;

  @Prop({ type: Boolean })
  private hiddenIndex;

  //用来判断是否合并单元格
  @Prop({ type: Boolean })
  private isSpan;

  @Prop({
    type: String,
    default: "序号"
  })
  private indexLabel;
  // 列样式
  @Prop({
    type: Function,
    default: () => ""
  })
  private rowClassName;
  // 斑马线
  @Prop({
    default: true
  })
  private stripe: boolean;

  // 合并行对应的键
  @Prop({
    type: String
  })
  private rowSpanKey;

  /**
   * 是否展示caseMark
   */
  @Prop({ type: Boolean, default: false })
  private showCaseMark: boolean;

  @Prop({ type: Function })
  private cellStyle;

  /**
   *  清除选择项
   */
  public clearSelection() {
    this.table.clearSelection();
    this.table.setCurrentRow();
  }

  @Watch("isSelectAll", { immediate: true }) private isSelect() {
    if (this.isSelectAll && this.data && this.data.length !== 0) {
      this.table.clearSelection();
    }
  }

  @Emit("onRowClick")
  private onRowClick(row, event, column) {}
  // 分页信息改变消息
  @Emit("onPageChange")
  private pageConfigChange(page) {
    return page;
  }
  // 更新选择项列表
  @Emit("update:selectionList")
  private updateSelectionList(list) {
    return list;
  }
  // 更新当前选择项
  @Emit("update:selectionRow")
  private updateSelectionRow(row) {}

  // 监听当前选中行变化
  @Watch("selectionRow", { immediate: true })
  private onSelectionRowChange(val: string, oldVal: string) {
    this.$nextTick(() => {
      this.table.setCurrentRow(val);
    });
  }

  // private;

  // 监听当前选中列表变化
  @Watch("selectionList", { immediate: true })
  private onSelectionListChanged(val: any[], oldVal: any[]) {
    if (!val) {
      return;
    }
    //  等待data 渲染完毕之后再进行选中行赋值
    this.$nextTick(() => {
      this.data.forEach(row => {
        const checkFlag = this.selectionList.includes(row);
        this.table.toggleRowSelection(row, checkFlag);
      });
    });
  }

  private tableHeight() {
    if (this.height === "") {
      return this.maxHeight;
    } else {
      return this.height;
    }
  }

  private get userId () {
    return this.userData.id;
  }

  private checkbox(row, rowIndex) {
    if(this.approvalUse) { // 只有审批可以勾选
      return row.applyStatus === 'PENDING' && row.checkUserLinkedList.includes(this.userId)
    } else {
      return !this.isSelectAll ? true : false;
    }
  }

  private cellClass(row) {
    // 全选复选框样式
    if (this.isSelectAll) {
      return "disabledCheck";
    }
  }

  private get showTopSlot() {
    return (
      this.$slots.buttons || this.$slots.append || this.$slots.caseTotalInfo
    );
  }

  private get emptyText() {
    return this.data ? "暂无数据" : " ";
  }
  /**
   * 组件初始化
   */
  private mounted() {
    this.table = this.$refs["table"] as any;
  }

  /**
   * 监听绑定数据变化
   */
  @Watch("data")
  private onDataChanged(newVal: string, oldVal: string) {}

  /**
   * 页码数量变化回调
   */
  private pageSizeChange(value) {
    this.page.pageIndex = 1;
    this.page.pageSize = value;
    this.pageConfigChange(this.page);
  }

  /**
   * 页码位置变化回调
   */
  private pageIndexChange(value) {
    this.page.pageIndex = value;
    this.pageConfigChange(this.page);
  }

  /**
   * 排序改变
   */
  private onSortChange({ column, prop, order }) {
    if (this.sort) {
      this.sort.update(prop, order);
      this.pageConfigChange(this.page);
    }
  }

  private rowStyle({ row, rowIndex }) {
    if (!this.showCaseMark) return;
    if (!row.caseMark) return;
    const color = CaseMarkColor.find(x => x.value === row.caseMark);
    if (color) {
      return {
        backgroundColor: color.color
      };
    }
  }

  private spanMethod({ row, column, rowIndex, columnIndex }) {
    if (!this.rowSpanKey) return;
    const columnProperty = this.rowSpanKey;
    if (column.property !== columnProperty) return;
    // 当前单元格的值
    const currentValue = row[columnProperty];
    const span = {
      rowspan: 0,
      colspan: 0
    };
    const beforRow = rowIndex > 0 ? this.data[rowIndex - 1] : null;
    if (beforRow && beforRow[columnProperty] === currentValue) return span;

    // 如果当前单元格的值与上一行的对应单元格的值一致，则合并行已经计算过
    span.colspan = 1;
    span.rowspan = 1;
    let nextRowIndex = rowIndex + 1;
    while (nextRowIndex < this.data.length) {
      // 如果下一行对应单元格的值与当前单元格的值一致
      const nextRowValue = this.data[nextRowIndex][columnProperty];
      if (nextRowValue === currentValue) span.rowspan += 1;
      nextRowIndex += 1;
    }
    return span;
  }
}
</script>

<style lang="less" scoped>
.component.data-box {
  padding: 10px;
  & > * {
    margin-bottom: 10px;
  }
}
</style>
<style lang="less">
.data-box.component {
  @line-height: 26px;
  .el-input-number {
    line-height: @line-height;
    width: inherit;
    &__decrease,
    &__increase {
      height: calc(@line-height - 2px);

      width: 35px;
    }
    &__increase {
      right: 5px;
    }
    &__decrease {
      left: 5px;
    }
  }
  .disabledCheck > .cell .el-checkbox__inner {
    display: none !important;
  }
}
.location {
  position: relative;
}
</style>
